﻿//=================================================== 
// 
// 文件名 :EncoderAdpters 
// 简介: 
// 作者： 小钟
// 日期：2009-7-10 11:34:03 
// 
//====================================================

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace GCELibrary.Current.VideoEncoder
{
    public interface IEncoderAdpter
    {
        /// <summary>
        ///  编码
        /// </summary>
        /// <param name="inputFile"></param>
        /// <param name="outputFile"></param>
        /// <returns></returns>
        bool VideoEncode(string inputFile, string outputFile);
        /// <summary>
        ///  截图
        /// </summary>
        /// <param name="inputVideoFile"></param>
        /// <param name="outputImgFile"></param>
        /// <param name="imgTime"></param>
        /// <returns></returns>
        bool CatchImg(string inputVideoFile, string outputImgFile, string imgTime);
    }

    public class FFMepgAdpter : IEncoderAdpter
    {
        #region IEncoderAdpter 成员

        bool IEncoderAdpter.VideoEncode(string inputFile, string outputFile)
        {
            StringBuilder sb = new StringBuilder();
            // 命令参数
            sb.Append(string.Format(" -i {0}", inputFile));                     // 转换文件
            sb.Append(string.Format(" -s {0}x{1}", EncoderConfig.VideoWidth, EncoderConfig.VideoHeight));   // 尺寸

            // 帧数          
            sb.Append(string.Format(" -r {0}", EncoderConfig.Fps));
            // 音频采样率
            sb.Append(string.Format(" -ar {0}", EncoderConfig.Freq));
            // 音频解码率
            sb.Append(string.Format(" -ab {0}", EncoderConfig.SoundBitrate));
            // 视频比特率
            sb.Append(string.Format(" -b {0}", EncoderConfig.VideoBitrate));
            // 作者
            sb.Append(string.Format(" -author {0}", EncoderConfig.Author));
            // 版权
            sb.Append(string.Format(" -copyright {0}", EncoderConfig.Copyright));
            // 标题
           sb.Append(string.Format(" -title {0}", EncoderConfig.Title));

            // 水印图片
           if (EncoderConfig.NeedWaterLogo)
            {
                //sb.AppendFormat("-f {0} -x {1} -y -{2} -w {3} -h {4}",
                //    LogoWaterMark.LogoPic,
                //    LogoWaterMark.LeftMargin,
                //    LogoWaterMark.TopMargin,
                //    LogoWaterMark.Width,
                //    LogoWaterMark.Height);
                //sb.AppendFormat("-tagpict  \":{0}:{1}\"", LogoWaterMark.LeftMargin, LogoWaterMark.TopMargin);

            }

            // 视频截图
           if (EncoderConfig.NeedCatchImg)
            {
                //sb.AppendFormat("-f image2 -ss {0} -s {1}x{2} -vframes {3} '{4}'",
                //    VideoPic.Second,
                //    VideoPic.PicWidth,
                //    VideoPic.PicHeight,
                //    VideoPic.FrameCount,
                //    VideoPic.PicUrl);
            }

            sb.Append(string.Format(" {0} ", outputFile));                      // 保存地址

            bool resualt = false;
            try
            {
                // 新的进程对象
                Process pro = new Process();

                pro.StartInfo.FileName = EncoderConfig.ToolFile;   // ffmpeg程序 
                pro.StartInfo.Arguments = sb.ToString();        // 命令参数
                pro.StartInfo.UseShellExecute = false;          // 关闭Shell的使用

                //pro.StartInfo.RedirectStandardInput = true; //重定向标准输入 
                //pro.StartInfo.RedirectStandardOutput = true; //重定向标准输出 
                //pro.StartInfo.RedirectStandardError = true; //重定向错误输出 
                //pro.StartInfo.CreateNoWindow = false; ; //设置不显示窗口 

                resualt = pro.Start();  // 执行进程
            }
            catch
            {
                resualt = false;
            }
            return resualt;
        }
        /// <summary>
        ///  抓去截图
        /// </summary>
        /// <param name="inputVideoFile"></param>
        /// <param name="outputImgFile"></param>
        /// <param name="imgTime"></param>
        /// <returns></returns>
        bool IEncoderAdpter.CatchImg(string inputVideoFile, string outputImgFile, string imgTime)
        {
            return false;
        }

        #endregion
    }

    public class MencoderAdpter : IEncoderAdpter
    {
        #region IEncoderAdpter 成员

        bool IEncoderAdpter.VideoEncode(string inputFile, string outputFile)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append(string.Format(" {0}", inputFile));        // 视频文件
            sb.Append(string.Format(" -o {0}", outputFile));    // 转换后保存路径

            sb.Append(" -of lavf ");                            // 由libavformat 支持的一种容器
            //sb.Append(" -lavfopts i_certify_that_my_video_stream_does_not_use_b_frames"); // 文档上解释,转换flv最好加上此参数,可防止出错
            sb.Append(" -oac mp3lame:"); // 音频解码器
            sb.Append(string.Format(" -lameopts abr:br={0}", EncoderConfig.SoundBitrate));   // 设置音频解码器
            sb.Append(" -ovc lavc");    // 输出视频编码器

            sb.Append(string.Format(" -lavcopts vcodec=flv:vbitrate={0}:mbd=2:mv0:v4mv:trell:cbp:last_pred=3:dia=4:cmp=6:vb_strategy=1", EncoderConfig.VideoBitrate));    // 设置视频解码器,最重要vcodec=flv指定格式

            sb.Append(string.Format(" -ofps {0}", EncoderConfig.Fps));     // 输出帧率
            sb.Append(string.Format(" -srate {0}", EncoderConfig.Freq));   // 音频采样率
            sb.Append(string.Format(" -vf  scale={0}:{1}", EncoderConfig.VideoWidth, EncoderConfig.VideoHeight)); // 转换尺寸
            bool resualt = false;
            //bool proExit = false;
            //try
            //{
            //    // 新的进程对象
            //    Process pro = new Process();
            //    Guid guid = new Guid();
            //    FileInfo fileInfo = new FileInfo(outputFile);
            //    int timeCount = 0;
            //    long fileLength = 0;
            //    guid = BLL.TimeTriggerService.Instance.Register(delegate()
            //    {
            //        //如果正则退出则表示转换成功
            //        if (pro.HasExited)
            //        {
            //            proExit = true;
            //            resualt = resualt && true;
            //            BLL.TimeTriggerService.Instance.UnRegister(guid);//注销时间线程
            //        }
            //        else
            //        {
            //            if (!fileInfo.Exists)
            //                timeCount++;
            //            else
            //            {
            //                if (fileInfo.Length == fileLength)
            //                    timeCount++;
            //                else
            //                    fileLength = fileInfo.Length;
            //            }
            //            //如果三次文件的大小没有改变，那么为死进程，结束进程后把结果设为false
            //            if (timeCount > 3 && fileInfo.Length == fileLength)
            //            {
            //                pro.Kill();
            //                proExit = true;
            //                resualt = false;
            //                //注销时间线程
            //                BLL.TimeTriggerService.Instance.UnRegister(guid);
            //            }
            //        }
            //    }, new TimeSpan(0, 0, 3));
            //    pro.StartInfo.FileName = EncoderConfig.ToolFile;   // mencoder程序 
            //    pro.StartInfo.Arguments = sb.ToString();        // 命令参数
            //    pro.StartInfo.UseShellExecute = false;          // 关闭Shell的使用
            //    resualt = pro.Start();  // 执行进程
            //}
            //catch
            //{
            //    resualt = false;
            //}
            //do
            //{
            //    System.Threading.Thread.Sleep(1000);
            //} while (!proExit);
            return resualt;
        }

        bool IEncoderAdpter.CatchImg(string inputVideoFile, string outputImgFile, string imgTime)
        {
            return false;
        }

        #endregion
    }
}
